﻿-----------------------------------------------------------------------------------------------
------------------------------- Funciones pca_almacen.familias --------------------------------
-----------------------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION pca_almacen.fn_add_familia(varchar,--nombre_familia $1
						      varchar --nombre_sub_familia $2
						      )RETURNS void AS
$$
BEGIN
	$1 := initcap(trim(both ' ' from $1));
	$2 := initcap(trim(both ' ' from $2));
	
	IF NOT EXISTS (SELECT 
				nombre_familia,
				nombre_sub_familia
			    FROM
				pca_almacen.familias
			    WHERE
				nombre_familia=$1 AND
				nombre_sub_familia=$2)THEN
		INSERT INTO 
			pca_almacen.familias
		VALUES
			($1,$2);
	END IF;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_update_familia(varchar,--nombre_familia OLD $1
						         varchar --nombre_familia NEW $2
							 )RETURNS void AS
$$
BEGIN
	$2 := initcap(trim(both ' ' from $2));
	
	UPDATE
		pca_almacen.familias
	SET
		nombre_familia = $2
	WHERE
		nombre_familia = $1;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_update_familia(varchar,--nombre_familia OLD $1
						         varchar,--nombre_sub_familia OLD $2
						         varchar,--nombre_familia NEW $3
						         varchar --nombre_sub_familia NEW $4
							 )RETURNS void AS
$$
BEGIN
	$1 := trim(both ' ' from $1);
	$2 := trim(both ' ' from $2);
	$3 := initcap(trim(both ' ' from $3));
	$4 := initcap(trim(both ' ' from $4));

	IF NOT EXISTS 
		(SELECT 
			nombre_familia,
			nombre_sub_familia
		FROM
			pca_almacen.familias
		WHERE
			nombre_familia = $3 AND
			nombre_sub_familia = $4) THEN

		UPDATE
			pca_almacen.familias
		SET
			nombre_familia = $3,
			nombre_sub_familia = $4
		WHERE
			nombre_familia = $1 AND
			nombre_sub_familia = $2;
	ELSE
		IF($1<>$3 AND $2<>$4)THEN
			RAISE EXCEPTION 'Ya existe una Familia : % Sub Familia : %',$3,$4;
		END IF;
	END IF;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_del_familia(varchar --nombre_familia $1
						      )RETURNS void AS
$$
BEGIN
	DELETE FROM 
		pca_almacen.familias
	WHERE
		nombre_familia = $1;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_del_familia(varchar,--nombre_familia $1
						      varchar --nombre_sub_familia $2
						      )RETURNS void AS
$$
BEGIN
	DELETE FROM 
		pca_almacen.familias
	WHERE
		nombre_familia = $1 AND
		nombre_sub_familia = $2;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_list_familia()RETURNS SETOF pca_almacen.familias AS
$$
DECLARE
	_row pca_almacen.familias%ROWTYPE;
BEGIN
	FOR _row IN
		SELECT DISTINCT ON(nombre_familia)
			nombre_familia,
			nombre_sub_familia
		FROM
			pca_almacen.familias
		ORDER BY
			nombre_familia ASC,
			nombre_sub_familia ASC
	LOOP
		RETURN NEXT _row;
	END LOOP;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_list_familia(varchar --nombre_familia $1
							   )RETURNS SETOF pca_almacen.familias AS
$$
DECLARE
	_row pca_almacen.familias%ROWTYPE;
BEGIN
	FOR _row IN
		SELECT DISTINCT ON(nombre_familia)
			nombre_familia,
			nombre_sub_familia
		FROM
			pca_almacen.familias
		WHERE
			lower(pca_global.fn_ascii(nombre_familia)) LIKE '%'|| lower(pca_global.fn_ascii($1)) ||'%'
		ORDER BY
			nombre_familia ASC
	LOOP
		RETURN NEXT _row;
	END LOOP;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_list_sub_familia(varchar --nombre_familia $1
							       )RETURNS SETOF pca_almacen.familias AS
$$
DECLARE
	_row pca_almacen.familias%ROWTYPE;
BEGIN
	FOR _row IN
		SELECT
			nombre_familia,
			nombre_sub_familia
		FROM
			pca_almacen.familias
		WHERE
			lower(pca_global.fn_ascii(nombre_familia)) = lower(pca_global.fn_ascii($1))
		ORDER BY
			nombre_familia ASC
	LOOP
		RETURN NEXT _row;
	END LOOP;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_list_sub_familia(varchar,--nombre_familia $1
							       varchar --nombre_sub_familia $2
							       )RETURNS SETOF pca_almacen.familias AS
$$
DECLARE
	_row pca_almacen.familias%ROWTYPE;
BEGIN
	FOR _row IN
		SELECT
			nombre_familia,
			nombre_sub_familia
		FROM
			pca_almacen.familias
		WHERE
			lower(pca_global.fn_ascii(nombre_familia)) = lower(pca_global.fn_ascii($1)) AND
			lower(pca_global.fn_ascii(nombre_sub_familia)) LIKE '%'|| lower(pca_global.fn_ascii($2)) ||'%'
		ORDER BY
			nombre_familia ASC
	LOOP
		RETURN NEXT _row;
	END LOOP;
END;
$$
LANGUAGE plpgsql;

-----------------------------------------------------------------------------------------------
------------------------------- Funciones pca_almacen.marcas ----------------------------------
-----------------------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION pca_almacen.fn_add_marca(varchar --nombre_marca $1
						    )RETURNS void AS
$$
BEGIN
	$1 := initcap(trim(both ' ' from $1));
	
	IF NOT EXISTS 
		(SELECT 
			nombre_marca
		FROM
			pca_almacen.marcas
		WHERE
			nombre_marca=$1)THEN

		INSERT INTO 
			pca_almacen.marcas
		VALUES
			($1);
	END IF;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_update_marca(varchar,--nombre_marca OLD $1
						       varchar --nombre_marca NEW $2
						       )RETURNS void AS
$$
BEGIN
	$1 := trim(both ' ' from $1);
	$2 := initcap(trim(both ' ' from $2));
	
	IF NOT EXISTS
		(SELECT 
			nombre_marca
		FROM
			pca_almacen.marcas
		WHERE
			nombre_marca=$2)THEN

		UPDATE
			pca_almacen.marcas
		SET
			nombre_marca = $2
		WHERE
			nombre_marca = $1;
	ELSE
		IF($1<>$2)THEN
			RAISE EXCEPTION 'Ya existe la marca %',$2;
		END IF;
	END IF;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_del_marca(varchar --nombre_marca $1
						    )RETURNS void AS
$$
BEGIN
	DELETE FROM 
		pca_almacen.marcas
	WHERE
		nombre_marca = $1;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_list_marcas()RETURNS SETOF pca_almacen.marcas AS
$$
DECLARE
	_row pca_almacen.marcas%ROWTYPE;
BEGIN
	FOR _row IN
		SELECT
			nombre_marca
		FROM
			pca_almacen.marcas
		ORDER BY 
			nombre_marca ASC
	LOOP
		RETURN NEXT _row;
	END LOOP;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_list_marcas(varchar --nombre_marca $1
							 )RETURNS SETOF pca_almacen.marcas AS
$$
DECLARE
	_row pca_almacen.marcas%ROWTYPE;
BEGIN
	FOR _row IN
		SELECT
			nombre_marca
		FROM
			pca_almacen.marcas
		WHERE
			lower(pca_global.fn_ascii(nombre_marca)) LIKE '%'|| lower(pca_global.fn_ascii($1)) ||'%'
		ORDER BY 
			nombre_marca ASC
	LOOP
		RETURN NEXT _row;
	END LOOP;
END;
$$
LANGUAGE plpgsql;

-----------------------------------------------------------------------------------------------
----------------------------- Funciones pca_almacen.articulos ---------------------------------
-----------------------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION pca_almacen.fn_add_articulo(varchar,--nombre_familia $1
						       varchar,--nombre_sub_familia $2
						       varchar,--nombre_marca $3
						       varchar,--cod_interno $4
						       text,--cod_barras $5
						       varchar,--nombre_corto $6
						       text,--descripcion $7
						       text,--keywords $8
						       integer --tipo_articulo_id $9
						       )RETURNS bigint AS
$$
BEGIN
	$1 = initcap(trim(both ' ' from $1));
	$2 = initcap(trim(both ' ' from $2));
	$3 = initcap(trim(both ' ' from $3));
	$6 = upper(trim(both ' ' from $6));
	$7 = initcap(trim(both ' ' from $7));
	$8 = initcap(trim(both ' ' from $8));

	execute pca_almacen.fn_add_familia($1,$2);

	execute pca_almacen.fn_add_marca($3);

	IF($5 ISNULL)THEN
		INSERT INTO pca_almacen.articulos
			(nombre_familia,
			nombre_sub_familia, 
			nombre_marca,
			cod_interno,
			nombre_corto,
			descripcion,
			keywords,
			tipo_articulo_id)
		VALUES
			($1,$2,$3,$4,$6,$7,$8,$9);
	ELSE
		INSERT INTO pca_almacen.articulos
			(nombre_familia,
			nombre_sub_familia, 
			nombre_marca,
			cod_interno,
			cod_barras,
			nombre_corto,
			descripcion,
			keywords,
			tipo_articulo_id)
		VALUES
			($1,$2,$3,$4,$5,$6,$7,$8,$9);
	END IF;

	RETURN pca_global.fn_pseudo_encrypt_bigint(currval('pca_almacen.seq_articulos_id')::integer);
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_update_articulo(bigint,--articulo_id $1
							  varchar,--nombre_familia $2
						          varchar,--nombre_sub_familia $3
						          varchar,--nombre_marca $4
						          varchar,--cod_interno $5
						          text,--cod_barras $6
						          varchar,--nombre_corto $7
						          text,--descripcion $8
						          text,--keywords $9
						          integer --tipo_articulo_id $10
						          )RETURNS void AS
$$
BEGIN
	$2 = initcap(trim(both ' ' from $2));
	$3 = initcap(trim(both ' ' from $3));
	$4 = initcap(trim(both ' ' from $4));
	$7 = upper(trim(both ' ' from $7));
	$8 = initcap(trim(both ' ' from $8));
	$9 = initcap(trim(both ' ' from $9));

	execute pca_almacen.fn_add_familia($2,$3);

	execute pca_almacen.fn_add_marca($4);

	IF($5 ISNULL)THEN
		UPDATE pca_almacen.articulos SET
			nombre_familia=$2,
			nombre_sub_familia=$3, 
			nombre_marca=$4,
			cod_interno=$5,
			cod_barras=articulo_id,
			nombre_corto=$7,
			descripcion=$8,
			keywords=$9,
			tipo_articulo_id=$10
		WHERE
			articulo_id=$1;
	ELSE
		UPDATE pca_almacen.articulos SET
			nombre_familia=$2,
			nombre_sub_familia=$3, 
			nombre_marca=$4,
			cod_interno=$5,
			cod_barras=$6,
			nombre_corto=$7,
			descripcion=$8,
			keywords=$9,
			tipo_articulo_id=$10
		WHERE
			articulo_id=$1;
	END IF;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_del_articulo(bigint --articulo_id $1
							)RETURNS void AS
$$
BEGIN
	DELETE FROM 
		pca_almacen.articulos
	WHERE
		articulo_id=$1;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_articulo(bigint --articulo_id $1
							)RETURNS pca_almacen.articulos AS
$$
DECLARE
	_row pca_almacen.articulos%ROWTYPE;
BEGIN
	SELECT
		articulo_id,
		nombre_familia,
		nombre_sub_familia,
		nombre_marca,
		cod_interno,
		cod_barras,
		nombre_corto,
		descripcion,
		keywords,
		fecha_registro,
		activo,
		tipo_articulo_id 
	INTO
		_row
	FROM
		pca_almacen.articulos
	WHERE
		articulo_id = $1;

	IF(FOUND)THEN
		RETURN _row;
	ELSE
		RAISE EXCEPTION 'No existe articulo con ID = %',$1;
	END IF;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_list_articulo(integer,--start $1
							    integer,--limit $2
							    integer --tipo_articulo_id $3
							    )RETURNS SETOF refcursor AS
$$
DECLARE
	cursor_result refcursor;
	cursor_totalrows refcursor;
BEGIN
	OPEN cursor_result FOR
		SELECT
			articulo_id,
			nombre_familia,
			nombre_sub_familia,
			nombre_marca,
			cod_interno,
			cod_barras,
			nombre_corto,
			descripcion,
			keywords,
			fecha_registro,
			activo,
			tipo_articulo_id
		FROM
			pca_almacen.articulos
		WHERE
			tipo_articulo_id = $3
		ORDER BY
			fecha_registro ASC LIMIT $2 OFFSET $1;
	RETURN NEXT cursor_result;

	OPEN cursor_totalrows FOR
		SELECT
			count(articulo_id)
		FROM
			pca_almacen.articulos
		WHERE
			tipo_articulo_id = $3;
	RETURN NEXT cursor_totalrows;	
END;
$$
LANGUAGE plpgsql;

--Busca articulos por nombre corto o codigo interno
CREATE OR REPLACE FUNCTION pca_almacen.fn_get_list_articulo(integer,--start $1
							    integer,--limit $2
							    integer,--tipo_articulo_id $3
							    varchar --nombre corto | cod_interno | descripcion | keywords $4
							    )RETURNS SETOF refcursor AS
$$
DECLARE
	cursor_result refcursor;
	cursor_totalrows refcursor;
BEGIN
	OPEN cursor_result FOR
		SELECT
			articulo_id,
			nombre_familia,
			nombre_sub_familia,
			nombre_marca,
			cod_interno,
			cod_barras,
			nombre_corto,
			descripcion,
			keywords,
			fecha_registro,
			activo,
			tipo_articulo_id
		FROM
			pca_almacen.articulos
		WHERE
			tipo_articulo_id = $3 AND
			(lower(pca_global.fn_ascii(nombre_corto)) LIKE '%'|| lower(pca_global.fn_ascii($4)) ||'%' OR
			lower(pca_global.fn_ascii(cod_interno)) LIKE '%'|| lower(pca_global.fn_ascii($4)) ||'%' OR 
			lower(pca_global.fn_ascii(descripcion)) LIKE '%'|| lower(pca_global.fn_ascii($4)) ||'%' OR
			lower(pca_global.fn_ascii(keywords)) LIKE '%'|| lower(pca_global.fn_ascii($4)) ||'%')
		ORDER BY
			fecha_registro ASC LIMIT $2 OFFSET $1;
	RETURN NEXT cursor_result;

	OPEN cursor_totalrows FOR
		SELECT
			count(articulo_id)
		FROM
			pca_almacen.articulos
		WHERE
			tipo_articulo_id = $3 AND
			(lower(pca_global.fn_ascii(nombre_corto)) LIKE '%'|| lower(pca_global.fn_ascii($4)) ||'%' OR
			lower(pca_global.fn_ascii(cod_interno)) LIKE '%'|| lower(pca_global.fn_ascii($4)) ||'%' OR 
			lower(pca_global.fn_ascii(descripcion)) LIKE '%'|| lower(pca_global.fn_ascii($4)) ||'%' OR
			lower(pca_global.fn_ascii(keywords)) LIKE '%'|| lower(pca_global.fn_ascii($4)) ||'%');
	RETURN NEXT cursor_totalrows;	
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_list_articulo(integer,--start $1
							    integer, --limit $2
							    integer,--tipo_articulo_id $3
							    varchar[] --filtros $4
							    )RETURNS SETOF refcursor AS
$$
DECLARE
	cursor_result refcursor;
	cursor_totalrows refcursor;
	sqlfiltro varchar;
	sqlcount varchar;
BEGIN
	$4 := $4 || ARRAY[['numeric','eq',$3::varchar,'tipo_articulo_id']];

	sqlfiltro := 
		'SELECT
			articulo_id,
			nombre_familia,
			nombre_sub_familia,
			nombre_marca,
			cod_interno,
			cod_barras,
			nombre_corto,
			descripcion,
			keywords,
			fecha_registro,
			activo,
			tipo_articulo_id
		FROM
			pca_almacen.articulos
		WHERE '|| 
			pca_global.fn_get_strfiltro($4)|| 
		' ORDER BY
			fecha_registro ASC LIMIT '|| $2 || ' OFFSET '|| $1 ;

	sqlcount := 
		'SELECT
			count(articulo_id)
		FROM
			pca_almacen.articulos
		WHERE '|| 
			pca_global.fn_get_strfiltro($4);
	
	OPEN cursor_result FOR
		EXECUTE(sqlfiltro);
	RETURN NEXT cursor_result;

	OPEN cursor_totalrows FOR
		EXECUTE(sqlcount);
	RETURN NEXT cursor_totalrows;	
END;
$$
LANGUAGE plpgsql;

-----------------------------------------------------------------------------------------------
------------------------------ Funciones  pca_almacen.fotos -----------------------------------
-----------------------------------------------------------------------------------------------

CREATE OR REPLACE FUNCTION pca_almacen.fn_add_foto(bigint,--articulo_id $1
						   varchar,--nombre $2
						   text --ruta $3
						   )RETURNS bigint AS
$$
BEGIN
	$2 := initcap(trim(both ' ' from $2));
	
	INSERT INTO pca_almacen.fotos
		(articulo_id,
		nombre,
		ruta)
	VALUES
		($1,$2,$3);
		
	RETURN pca_global.fn_pseudo_encrypt_bigint(currval('pca_almacen.seq_fotos_id')::integer);
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_update_foto(bigint,--foto_id $1
						      varchar, --nombre $2
						      varchar --ruta $3
						      )RETURNS void AS
$$
BEGIN
	$2 := initcap(trim(both ' ' from $2));
	
	UPDATE pca_almacen.fotos SET
		nombre=$2,
		ruta =$3
	WHERE
		foto_id=$1;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_del_foto(bigint --foto_id $1
						   )RETURNS void AS
$$
BEGIN
	DELETE FROM  
		pca_almacen.fotos
	WHERE
		foto_id=$1;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_predeterminar_foto(bigint,--foto_id $1
							     bigint --articulo_id $2
						             )RETURNS void AS
$$	
DECLARE
	_row RECORD;
BEGIN
	FOR _row IN
		SELECT
			foto_id
		FROM
			pca_almacen.fotos
		WHERE
			articulo_id=$2
	LOOP
		IF(_row.foto_id = $1)THEN
			UPDATE pca_almacen.fotos SET
				predeterminado=true
			WHERE
				foto_id=_row.foto_id;
		ELSE
			UPDATE pca_almacen.fotos SET
				predeterminado=false
			WHERE
				foto_id=_row.foto_id;
		END IF;
	END LOOP;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_foto(bigint --foto_id $1
						   )RETURNS pca_almacen.fotos AS
$$
DECLARE
	_row pca_almacen.fotos%ROWTYPE;
BEGIN
	SELECT
		foto_id,
		articulo_id,
		nombre,
		ruta,
		fecha_registro,
		predeterminado
	INTO
		_row
	FROM
		pca_almacen.fotos
	WHERE
		foto_id=$1;

	RETURN _row;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE FUNCTION pca_almacen.fn_get_list_fotos(bigint --articulo_id $1
							 )RETURNS SETOF pca_almacen.fotos AS
$$
DECLARE
	_row pca_almacen.fotos%ROWTYPE;
BEGIN
	FOR _row IN
		SELECT
			foto_id,
			articulo_id,
			nombre,
			ruta,
			fecha_registro,
			predeterminado
		FROM
			pca_almacen.fotos
		WHERE
			articulo_id=$1
		ORDER BY
			fecha_registro
	LOOP
		RETURN NEXT _row;
	END LOOP;
END;
$$
LANGUAGE plpgsql;